﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="TemporaryStudyDefinitionDomainService.cs" company="ELEN 7045 GROUP II">
//    Contributed by E.Vosloo
// </copyright>
// <summary>
//   StudyDefinition Preparation Domain Service
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Domain.StudyDefinition.Services
{
    #region

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;

    using Domain.StudyDefinition.Contracts.DomainServices;
    using Domain.StudyDefinition.Contracts.Repositories.Studies;
    using Domain.StudyDefinition.Contracts.Repositories.SubjectGroups;
    using Domain.StudyDefinition.Contracts.Repositories.Treatments;
    using Domain.StudyDefinition.Entities;

    #endregion

    /// <summary>
    /// StudyDefinition Preparation Domain Service
    /// </summary>
    public class StudyDefinitionPreparationDomainService : IStudyDefinitionPreparationDomainService
    {
        #region Constants and Fields

        /// <summary>
        /// The IStudyRepository Instance to use in this service.
        /// </summary>
        private readonly IStudyRepository studyRepositoryInstance;

        /// <summary>
        /// The ISubjectGroupRepository Instance to use in this service.
        /// </summary>
        private readonly ISubjectGroupRepository subjectGroupRepositoryInstance;

        /// <summary>
        /// The ITreatmentRepository Instance to use in this service.
        /// </summary>
        private readonly ITreatmentRepository treatmentRepositoryInstance;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="StudyDefinitionPreparationDomainService"/> class.
        /// </summary>
        /// <param name="studyRepository">
        /// The study repository dependency.
        /// </param>
        /// <param name="subjectGroupRepository">
        /// The subject group repository dependency.
        /// </param>
        /// <param name="treatmentRepository">
        /// The treatment repository dependency.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Exception indicating that an argument was null
        /// </exception>
        public StudyDefinitionPreparationDomainService(
            IStudyRepository studyRepository, 
            ISubjectGroupRepository subjectGroupRepository, 
            ITreatmentRepository treatmentRepository)
        {
            if (studyRepository == null)
            {
                throw new ArgumentNullException("studyRepository");
            }

            if (subjectGroupRepository == null)
            {
                throw new ArgumentNullException("subjectGroupRepository");
            }

            if (treatmentRepository == null)
            {
                throw new ArgumentNullException("treatmentRepository");
            }

            this.studyRepositoryInstance = studyRepository;
            this.subjectGroupRepositoryInstance = subjectGroupRepository;
            this.treatmentRepositoryInstance = treatmentRepository;
        }

        #endregion

        #region Implemented Interfaces

        #region IStudyDefinitionPreparationDomainService

        /// <summary>
        /// Adds the specified study.
        /// </summary>
        /// <param name="study">
        /// The study to add.
        /// </param>
        /// <returns>
        /// The added study
        /// </returns>
        public Study AddStudy(Study study)
        {
            Dictionary<int, Treatment> persistedTreatments = new Dictionary<int, Treatment>();

            int addedTreatmentIndex = 0;
            foreach (Treatment treatment in study.Treatments)
            {
                var treatment1 = treatment;
                var persistedTreatment = this.treatmentRepositoryInstance.Get(t => t.Id == treatment1.Id).FirstOrDefault();
                persistedTreatments.Add(addedTreatmentIndex, persistedTreatment);

                foreach (var subjectGroup in treatment.SubjectGroups)
                {
                    var subjectGroup1 = subjectGroup;
                    var persistedSubjectGroup =
                        this.subjectGroupRepositoryInstance.Get(t => t.Id == subjectGroup1.Id).FirstOrDefault();

                    persistedTreatments[addedTreatmentIndex].SubjectGroups = new Collection<SubjectGroup>
                        {
                           persistedSubjectGroup 
                        };

                    // persistedTreatments[addedTreatmentIndex].SubjectGroups.Add(persistedSubjectGroup);
                }

                addedTreatmentIndex++;
            }

            foreach (var persistedTreatment in persistedTreatments)
            {
                study.Treatments.RemoveAt(persistedTreatment.Key);
                study.AddTreatment(persistedTreatment.Value);
            }

            var item = this.studyRepositoryInstance.Add(study);

            return item;
        }

        /// <summary>
        /// Adds the specified subjectGroup to the collection of SubjectGroups.
        /// </summary>
        /// <param name="subjectGroup">
        /// The subjectGroup to add.
        /// </param>
        /// <returns>
        /// The added subjectGroup
        /// </returns>
        public SubjectGroup AddSubjectGroup(SubjectGroup subjectGroup)
        {
            var item = this.subjectGroupRepositoryInstance.Add(subjectGroup);

            return item;
        }

        /// <summary>
        /// Adds the specified treatment to the collection of Treatments.
        /// </summary>
        /// <param name="treatment">
        /// The treatment to add.
        /// </param>
        /// <returns>
        /// The added treatment
        /// </returns>
        public Treatment AddTreatment(Treatment treatment)
        {
            var item = this.treatmentRepositoryInstance.Add(treatment);

            return item;
        }

        #endregion

        #endregion
    }
}
